package com.cherrish.demo.nio;

import com.cherrish.demo.SocketConst;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * @author cherrish
 * @time 2019-04-26 16:14
 * @name NioServer
 * @desc:
 */
public class NioServer {

    public static void main(String[] args) {
        NioServer nioServer = new NioServer();
        nioServer.start();
    }

    Selector selector = null;
    ServerSocketChannel serverSocketChannel = null;

    public void start(){
        try {
            init();
            listen();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void init() throws IOException {
        //打开一个通道
        serverSocketChannel = ServerSocketChannel.open();

        //通道设置非阻塞
        serverSocketChannel.configureBlocking(false);

        //绑定端口号
        InetSocketAddress inetSocketAddress = new InetSocketAddress(SocketConst.ADDRESS, SocketConst.PORT);
        serverSocketChannel.socket().bind(inetSocketAddress);

        //注册
        selector = Selector.open();
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        System.out.println("Server started...");
    }

    private void listen() throws IOException {

        while (true){
            selector.select();
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                if(selectionKey.isAcceptable()){
                    SocketChannel channel = serverSocketChannel.accept();
                    channel.configureBlocking(false);
                    channel.register(selector, SelectionKey.OP_READ);
                }else if(selectionKey.isReadable()){
                    readAndReply(selectionKey);
                }
                iterator.remove();
            }
        }
    }

    private void readAndReply(SelectionKey selectionKey) throws IOException {
        SocketChannel channel = (SocketChannel) selectionKey.channel();
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        int len = channel.read(byteBuffer);
        if(-1 != len){
            String message = new String(byteBuffer.array()).trim();
            System.out.println("recv from client: " + message);
            channel.write(ByteBuffer.wrap("nihao".getBytes()));
        }else {
            channel.close();
        }
    }

}
